<?php
	//foo
	include_once("cmsConfig.php");
//	require_once('Cache/Lite.php');	
	include_once("imagesModule.php");
	
	$CMS_SEARCH_HIGHLIGHT_COLOURS = array("#ffff66","#A0FFFF","#99ff99","#ff9999","#ff66ff","#880000","#00aa00","#886800","#004699","#990099");
	$CMS_SEARCH_TEXT_COLOURS = 	array("black",  "black",  "black",  "black",  "black",  "white",  "white",  "white",  "white",  "white");
	
	//set a public user up so that the cmsDocument can be used on the public side.
	function setupPublicUser($uid = -1, $usertype = -1, $usernameSet = "Public") {
		global $db, $authInfo;
		if( ((!(isset($authInfo)) || $authInfo == ''))) {
			$password = '';
			if($uid == -1) {
				//get a uid the hightest in the db
				$uid = 2147483647;
			}
			$authInfo["uid"] = $uid;
			if($usertype == -1) {
				//get a usertype the hightest in the db
				$usertype = 2147483647;
			}
			$authInfo["usertype"] = $usertype;
			$authInfo["username"] = $usernameSet;
			$authInfo["password"] = '';
			
			$authInfo = (Object) $authInfo;
			//echo "Into public setup!!!";
			return $authInfo; 
		} else {
			$authInfo = (Object) $authInfo;
			return $authInfo;
		}
	}
	
	
	
	//creates a drop down option list from a query
	function optionList($attribs, $allowNulls=false, $defaultValue = null, $valueKey, $optionKey, $query, $db){
		$optionTree = new XML_Tree();		
		$optionRoot =& $optionTree->addRoot("select",null,$attribs);
		if ($allowNulls){
			$optionRoot->addChild("option","",array());
		}
		if ($db->canExecuteQueries() && $db->executeQuery($query) && ($db->numRows() > 0)) {
			while (($row = $db->nextRow())){
				$attribs = array("value"=>$row[$valueKey]);
				if (!is_null($defaultValue) && $defaultValue == $row[$valueKey]) {
					$attribs['selected'] = 'selected';
				}
				
				$option =& $optionRoot->addChild("option",$row[$optionKey], $attribs);
			}			
		} else {
			$optionRoot->addChild("option","N/A",array("value"=>""));			
		}		
		$optionRoot->dump();		
	}
	
	function myeval($matches) {
		$var = extractValueWithKeyFromArray($matches[1], $_REQUEST, extractValueWithKeyFromArray($matches[1], $_COOKIES, extractValueWithKeyFromArray($matches[1], $_SESSION, extractValueWithKeyFromArray($matches[1], $GLOBALS))));
		if ( is_array($var) || is_object($var) ) {
			if (isset($matches[2])) {
				eval ( '$var = $var' . $matches[2] . ';' );
			}
		}
		return $var;
	}

	function parseSourceQuery($sourcequery) {
		$sourcequery = preg_replace_callback('/<<[[:space:]]*?\$([a-zA-Z0-9_\x7f-\xff]*)(.*?)>>/', "myeval", $sourcequery);
		return $sourcequery;
	}
	
	function is_date(&$value) {
		if (is_null($value) || strlen(trim($value)) == 0) return false;
		return (strtotime($value)) !== -1;
	}
	
	//function 
	//turns a string into a mysql compatible date
	function dateFromString($format, $str, $notNullDate=true){
		$str = trim($str);
		
		if ($str == null || strlen($str) == 0 )
			return false;
			
		if (!$notNullDate && !isset($str)){
			return "0000-00-00";
		}
		//juggle the date :-)
		if ( preg_match("/^([0-9]{1,2})[\/-]([0-9]{1,2})[\/-]([0-9]{1,4})$/",$str)){
			// we still pass to strtotime to ensure that the date is valid
			preg_match_all("/^([0-9]{1,2})[\/-]([0-9]{1,2})[\/-]([0-9]{1,4})$/",$str,$bits);
			$str = $bits[3][0] . "-" . $bits[2][0] . "-" . $bits[1][0];			
		}
		$ts = strtotime($str);
		if (($ts) > 0 ){
			return date($format,$ts);
		} else {
			return false;
		}		
	}

	//tests check boxes
	function checkBoxSet($checkBoxVar){
		if ($checkBoxVar){
			return 1;
		} else {
			return 0;
		}
	}

	//creates a checkbox list from a query
	function checkBoxList($name, $query, $db, $checked){
		if ($db->canExecuteQueries() && $db->executeQuery($query) && ($db->numRows() > 0)) {
			$name .= "[]";
			$id=0;
//			while (($row = $db->nextRow())){
			for( $id=0; ($row=$db->nextRow()); $id++){

				$checkedTag = "";
				if(isset($checked[$row[0]])) {
					$checkedTag = "checked=\"checked\"";
				} 
				$labelId = $id . "_" . $name ;
				echo "<label class=\"cms_form_checkbox\" for=\"$labelId\"><input class=\"cms_form_checkbox\" type=\"checkbox\" id=\"". $labelId . "\" name=\"$name\" value=\"".$row[0]."\" $checkedTag> " . $row[1] ."</label>";				
			}	
		} else {
//			echo "No Options";			
		}
	}
	
	function selectBoxListVerticle($name, $query, $db, $checked, $formname, $attribs){

		$checkedFlipped = array_flip($checked);
		
		echo "<table border=\"0\" width=\"445\">";
		echo "<tr>";		
		if ($db->canExecuteQueries() && $db->executeQuery($query) && ($db->numRows() > 0)) {
			$name .= "[]";
			echo "<td width=\"385\">";
			echo "<select name=\"".$name."1\" size=\"5\" class=\"".$attribs['class']."\" id=\"" . $attribs['class'] . "1\">";//this does not get an id?
			while (($row = $db->nextRow())){
				//if row is not in checked add it here
				//if (){
				if(!isset($checkedFlipped[$row[0]])) {
					echo "<option value=\"".$row[0]."\">".$row[1]."</option>";
				}
			}	
			echo "</select>";
			echo "</td>";
		} else {
			echo "No Options";			
		}
		
		echo "<td width=\"60\" align=\"left\" valign=\"center\">";
		echo "<img src=\"/cms/images/include.gif\" onClick=\"javascript:includeItem('".$formname."','".$name."1','".$name."','".$name."[]');\"><br /><br />";
		echo "<img src=\"/cms/images/remove.gif\" onClick=\"javascript:removeItem('".$formname."','".$name."','".$name."1','".$name."[]');\"></td>";
		echo "</td></tr><tr><td width=\"385\">";
		
		
		if ($db->canExecuteQueries() && $db->executeQuery($query) && ($db->numRows() > 0)) {		
			//$db->resetIterator();
			echo "<select name=\"".$name."\" size=\"5\" multiple=\"true\" class=\"".$attribs['class']."\" id=\"" . $attribs['class'] . "\">";
			while (($row = $db->nextRow())){
				if(isset($checkedFlipped[$row[0]])) {
					echo "<option value=\"".$row[0]."\">".$row[1]."</option>";					
				}
			}			
			echo "</select>";
	$js = <<< EOD
<script>
		sel = document.forms['$formname']['$name'];
		sel.onsubmit = function () { selectAllElementsInSelect( document.forms['$formname']['$name'] ) };
</script>
EOD;
echo preg_replace('/[\r\n\t ]+/',' ', $js);
//echo $js;

			echo "</td><td></td>";
		};
		echo "</tr>";
		echo "</table>";
	}	


	function printDateInput($name, $attribs){
		//meh include the calendar once.
		//include_once('calendar/calendar.php');
		//$calendarCodeHasLoaded = true;
		//$calendar = new DHTML_Calendar('/cms/html/calendar/','en','calendar-contentbox',false);		
		//if (!$codeHasLoaded) echo $calendar->get_load_files_code();	
		//$calendar->make_input_field( array(), array_merge( array( 'name'=>$name ), $attribs) );
		static $calendarCodeHasLoaded = false;
		if (!$calendarCodeHasLoaded){
			print <<< EOD
<style type="text/css">@import url(/cms/html/calendar/calendar-contentbox.css);</style> 
<script type="text/javascript" src="/cms/html/calendar/calendar.js"></script> 
<script type="text/javascript" src="/cms/html/calendar/lang/calendar-en.js"></script> 
<script type="text/javascript" src="/cms/html/calendar/calendar-setup.js"></script>
EOD;
			$calendarCodeHasLoaded = true;
		}
		
		printTextInput($name,$attribs);
print <<< EOD
<a href="#" id="f-calendar-trigger-$name" ><img src="/cms/html/calendar/img.gif" border="0" /></a>
		<script>
			var cal_$name = Calendar.setup({
				"ifFormat":"%a %d %B %Y",
				"daFormat":"%a %d %B %Y",
				"ttFormat":"%a %d %B %Y",
				"button" : "f-calendar-trigger-$name",
				"inputField" : "cms_form_$name"
			});
		</script>
EOD;
	}
	
	function selectBoxList($name, $query, $db, $checked, $formname, $attribs){

		$checkedFlipped = array_flip($checked);
		
		echo "<table border=\"0\" width=\"310\">";
		echo "<tr>";		
		if ($db->canExecuteQueries() && $db->executeQuery($query) && ($db->numRows() > 0)) {
			$name .= "[]";
			echo "<td width=\"125\">";
			echo "<select name=\"".$name."1\" size=\"5\" class=\"".$attribs['class']."\" id=\"" . $attribs['class'] . "1\">";//this does not get an id?
			while (($row = $db->nextRow())){
				//if row is not in checked add it here
				//if (){
				if(!isset($checkedFlipped[$row[0]])) {
					echo "<option value=\"".$row[0]."\">".magicClean($row[1])."</option>";
				}
			}	
			echo "</select>";
			echo "</td>";
		} else {
			echo "No Options";			
		}
		
		echo "<td width=\"60\" align=\"center\" valign=\"center\">";
		echo "<img src=\"/cms/images/include.gif\" onClick=\"javascript:includeItem('".$formname."','".$name."1','".$name."','".$name."[]');\"><br /><br />";
		echo "<img src=\"/cms/images/remove.gif\" onClick=\"javascript:removeItem('".$formname."','".$name."','".$name."1','".$name."[]');\">";
		echo "</td>";
		
		if ($db->canExecuteQueries() && $db->executeQuery($query) && ($db->numRows() > 0)) {		
			//$db->resetIterator();
			echo "<td width=\"125\">";
			echo "<select name=\"".$name."\" size=\"5\" multiple=\"true\" class=\"".$attribs['class']."\" id=\"" . $attribs['class'] . "\">";
			while (($row = $db->nextRow())){
				if(isset($checkedFlipped[$row[0]])) {
					echo "<option value=\"".$row[0]."\">".magicClean($row[1])."</option>";					
				}
			}			
			echo "</select>";
	$js = <<< EOD
<script>
		sel = document.forms['$formname']['$name'];
		sel.onsubmit = function () { selectAllElementsInSelect( document.forms['$formname']['$name'] ) };
</script>
EOD;
echo preg_replace('/[\r\n\t ]+/',' ', $js);
//echo $js;

			echo "</td>";
		};
		echo "</tr>";
		echo "</table>";
	}		
	
	//prints a hyper line <A href='' />
	function printUrl($dest, $linkText, $attribs=array()){
		$attribs = processAttribs(array("href"=>$dest), $attribs);
		printHtmlElement("a", $linkText, $attribs);
	}
	
	//prints a check box
	function printCheckBox($name, $attribs){
		printHtmlElement("input","",processAttribs(array("type"=>"checkbox","name"=>$name), $attribs));
	}
	
	// a  text lable with a hidden field
	function printLabel($name, $labelText, $attribs){		
		print("$labelText");
		printHidden($name, $attribs);
	}
	
	// <INPUT type='hidden' />
	function printHidden($name, $attribs){
		printHtmlElement("input","",processAttribs(array("type"=>"hidden","name"=>$name), $attribs));		
	}
	
	// <INPUT type='file' />
	function printFileUploadBox($name, $attribs){
		printHtmlElement("input","",processAttribs(array("type"=>"file","name"=>$name),$attribs));
	}
	
	//this prints an html elment/tag
	function printHtmlElement($tag, $contents, $attribs=array()){
//		$htmlElement = new XML_Tree();
//		$htmlElementRoot =& $htmlElement->addRoot($tag,$contents,$attribs);
//		$htmlElementRoot->dump();
//		myPrintR($htmlElement);

		$a="";
		foreach ($attribs as $key => $value)	{
			$a .= " $key =\"$value\" ";
		}
		$node = "<$tag " . ( 0 < count($attribs) ?  ( $a )  : "" ) . ( true ? ">$contents</$tag" :"/") . ">";
		echo "$node";
//		return $node;
		
	}
	
	//this process attributes for html elements
	function processAttribs($coreAttribs, $optionalAttribs=null){
		if (is_array($optionalAttribs)){			
			return $coreAttribs  + $optionalAttribs;
		} else {
			return $coreAttribs;
		}
	}
	
	//the prints an <INPUT type="text" /> element
	function printTextInput($name, $attribs){
		printHtmlElement("input","",processAttribs(array("type"=>"text","name"=>$name),$attribs));
	}
	
	//prints an html <TEXTAREprintHtmlElementA /> with the given $name $contents and $attributes
	function printTextArea($name, $contents, $attribs){
		$coreAttribs = processAttribs(array("name"=>$name) , $attribs);
		printHtmlElement("textarea",$contents, $coreAttribs);
	}
	
	//this tidies up data returned from the database so it will show nicely in html
	function magicClean($value, $nl2br = CMS_MAGICCLEAN_LINEFEED_MUNGE){
		if (is_null($value)) return null;
		
		$value = trim($value);// remove trailing /leading white space..
		//do some mojo for dates that are returned like this YYYY-MM-DD from mysql
		if (strlen($value) == strlen("0000-00-00") && preg_match("/^[0-9]{4}-[0-9]{2}-[0-9]{2}/",$value)){
			return date("l j F Y",strtotime($value));
		} else if (strlen($value) == strlen("2006-04-10 13:26:55") && preg_match("/^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/",$value)){
			return date("l j F Y H:i:s",strtotime($value));

		} else {
			if ($nl2br){
				$value =  nl2br(stripslashes($value));
			} else {
				$value = stripslashes($value);
			}
		}
		//dont use this at the moment...
		//		if (isset($_REQUEST['keywords']) && isset($_REQUEST['highlight'])) {
		//			$keyWordList = keyWordReduce($_REQUEST['keywords']);
		//			$value = highlightKeyWords($value, $keyWordList, $_REQUEST['colourise']);
		//		} 

		//empty strings are evil...
		//if (is_string( $value ) && strlen($value <= 0 ) ) {
		//	$value = null;
		//}
		return $value;
	}

	//my own str_ireplace
	function str_Ireplace($search, $replace, $subject){
		return preg_replace("/" . $search . "/", $replace, $subject);
	}
	
	//reduces many spaces to one
	function reduceSpace($string) {
		return preg_replace("/\s+/"," ", $string);
	}

	//gets binary data from the content database, the object in the db must be docBlob
	function getBinaryData($documentCode, $cmsDocument, $attach=false, $scale = false, $width=null, $height=null) {
		die("DEPRECATED");
	}
	
	//gets binary data from the image database.
	function getFileBinaryData($document, $elementId = '', $filetypecode, $fileId, $db, $cmsDocument, $attach = false, $scale = false, $width=null, $height=null) {
		die("DEPRECATED");
	}
	
	//gets the description of the specifed docBlob
	function getBinaryFileDescription($documentCode, $db){
		
		$cmsDocument = new CmsDocument($db);
		$row = $cmsDocument->openDocument($documentCode);
		
		if ($row  && $row->documenttypecode=='docBlob'){
			$content = magicClean($row->shortdescription,false);
			print($content);
		}
	}
	
	// as the name says.. it sends an email message provided that the referrer is allowed to :)
	// $to - an array of recipients
	// $from - string, the sender
	// $cc - an array of recpients to be cc'd the message
	// $bcc - an array of recpients to be bcc'd the message
	// $subject - string/text the subject of the message
	// $body - string/text the message body..
	function simpleEmailer($to, $from, $cc, $bcc, $subject, $body, $param, $force = false){
		
		//if (refererCheck($force)){
			
			//required
			if (!is_null($from)) {
				$headers['From'] = $from; 
			} else {
				return false;
			}
			
			if (!is_null($to) && is_array($to)) {
				$headers['To'] = implode(",", $to);
			} else {
				return false;
			}
			
			//optional
			if (!is_null($subject)) { $headers['Subject'] = $subject; }
			if (!is_null($cc) && is_array($cc)) { $headers['Cc'] = implode(",",$cc); }
			if (!is_null($bcc) && is_array($bcc)) { $to = array_merge($to,$bcc); }
			
			$mailer =& Mail::factory('smtp', $param);
			
			if ( PEAR::isError( ($result = $mailer->send( implode(",", $to), $headers, $body))) ) {
				return false;
			} else {
				return true;
			}
		//}
	}
	
	// checks that a user is a valid user
	// can login. it checks for a cookie and if the cookie is set and not 
	// expired then we return true.. otherwise we redirect to the login page..
	function isRegisteredUser($db) {

		global $clientLogin;
		
	if(isset($clientLogin) && $clientLogin != '') {
			return true;
		} else {
			return false;
		} 
	}
	
	function isAdminUser($db) {

		global $authInfo, $username, $password;
		
		if($username && $password) {
		$authReader = new CmsTableWriter(CMS_AUTH_FORMAT,$db);
		if ($authReader->isReady()){
			$authReader->resetCustomIterator(" WHERE username='$username' LIMIT 1");
			$formDescriptior = new CmsTableWriter(CMS_FORM_DESC_FORMAT,$db);	
			$cmsDocument = new CmsDocument($db, session_id());
			if (($authInfo = $authReader->nextItem()) && ($authInfo->password == md5($password))){
				//valid auth, so remember me
				session_register("authInfo");
				return true;
			} else {
				//echo "!!!!!!!!!!!!!!!!!!!!!! 1.";
				return false;
			}
		} else {
			//echo "!!!!!!!!!!!!!!!!!!!!!! 2.";
			return false;
		}
		} else {
			return false;
		}
	}
	
	
	
	function makeTextSafe($string){
		//myPrintR($string);
		if (is_null($string)) return $string;
			
		global $CMS_DISALLOW_TAGS;
		
		$pattern = array();
		foreach ($CMS_DISALLOW_TAGS as $tag ){
			array_push($pattern,"/<\/?". preg_quote($tag) ."[^>]*>/ei");
		}
		return preg_replace($pattern,"",$string);
	}
		
	function cmsBrowserDet(){
		$ua = $_SERVER['HTTP_USER_AGENT'];
		$browser = array();
		
		//try and get the ua and the version
		if ( strpos($ua,"Gecko") !== false )  {
			if (strpos($ua, "Safari") !== false){
				$browser['browser'] = "Safari";
			// we can detect OmniWeb > 4.5 here as they are based on AppleWebKit which
			// returns as like gecko..
			} else if (strpos($ua, "OmniWeb") !== false) {
				$browser['browser'] = "OmniWeb";
				preg_match_all("/^.*OmniWeb\/([0-9]+)[.]([0-9]+)/",$ua,$bits);
				$browser['major'] = $bits[1][0];
				$browser['minor'] = $bits[2][0];			
			} else {
				
				if (strpos($ua,"Firebird") !== false) {
					$browser['browser'] = "Firebird";
					preg_match_all("/^.*Firebird\/([0-9]+)[.]([0-9]+)/",$ua,$bits);
					$browser['major'] = $bits[1][0];
					$browser['minor'] = $bits[2][0];
				} else if (strpos($ua,"Camino") !== false){
					$browser['browser'] = "Camino";
					preg_match_all("/^.*Camino\/([0-9]+)[.]([0-9]+)/",$ua,$bits);
					$browser['major'] = $bits[1][0];
					$browser['minor'] = $bits[2][0];
				} else if (strpos($ua,"Netscape") !== false){
					$browser['browser'] = "Netscape";
					preg_match_all("/^.*Netscape[0-9]?\/([0-9]+)[.]([0-9]+)/",$ua,$bits);
					$browser['major'] = $bits[1][0];
					$browser['minor'] = $bits[2][0];				
				} else {
					$browser['browser'] ="Mozilla";
					preg_match_all("/^.*[;]\s?rv[:]([0-9]+)[.]([0-9]+).?[)]/",$ua,$bits);
					$browser['major'] = $bits[1][0];
					$browser['minor'] = $bits[2][0];
				}
			}
		} else if (strpos($ua,"Mozilla") !== false){
			if (strpos($ua,"Opera") !== false) {
				$browser['browser'] = "Opera";
				preg_match_all("/^.*Opera\s*([0-9]+)[.]([0-9]+)/",$ua,$bits);
				$browser['major'] = $bits[1][0];
				$browser['minor'] = $bits[2][0];
			} else if (strpos($ua,"MSIE") !== false) {
				$browser['browser'] = "Internet Explorer";
				preg_match_all("/^.*[;]\s?MSIE.*([0-9]+)[.]([0-9]+)\s?[;]/",$ua,$bits);
				$browser['major'] = $bits[1][0];
				$browser['minor'] = $bits[2][0];
			} else {
				$browser['browser'] = "Netscape";
				$browser['browser'] ="Mozilla";
				preg_match_all("/^Mozilla\/([0-9]+)[.]([0-9]+)/",$ua,$bits);
				$browser['major'] = $bits[1][0];
				$browser['minor'] = $bits[2][0];
			}
		}
		return $browser;

	}
	
	//Send through the cmsDocument, the field in the database to be the value of the select box, the field in the
	//database to be the text of the select box, the field in the database which is the value of the first text box(
	// the one that on change it changes the second one), the name of the form, the name of the first select box, the 
	//name of the second select box, optional - the selected value... it should all work!
	function selects($cmsDocument, $selectValueField, $selectTextField, $constraintField, $formName, $constraintSelectName, $selectName, $selectedValue = Null) {
		$i = 0;
		?>
		<script language="javascript">
		createSelect();
		<?
                while ($row = $cmsDocument->nextDocument()) {
			echo "arrFunc(\"".$i."\",\"".$row->$selectValueField."\",\"".$row->$constraintField."\",\"".$row->$selectTextField."\",\"".$formName."\",\"".$constraintSelectName."\",\"".$selectName."\",\"".$selectedValue."\");\n";				
			$i = $i + 1;
                }		  
                ?>
		changeArea(<?= "'".$formName."','".$constraintSelectName."','".$selectName."','".$selectedValue."',''" ?>);		
		</script>
		<?
	}
	
	function selects2($cmsDocument, $selectValueField, $selectTextField, $constraintField, $formName, $constraintSelectName, $selectName, $selectedValue = Null) {
		$i = 0;
		?>
		<script language="javascript">
		createSelect2();
		<?
                while ($row = $cmsDocument->nextDocument()) {
			echo "arrFunc2(\"".$i."\",\"".$row->$selectValueField."\",\"".$row->$constraintField."\",\"".$row->$selectTextField."\",\"".$formName."\",\"".$constraintSelectName."\",\"".$selectName."\",\"".$selectedValue."\");\n";				
			$i = $i + 1;
                }		  
                ?>
		changeArea2(<?= "'".$formName."','".$constraintSelectName."','".$selectName."','".$selectedValue."'" ?>);		
		</script>
		<?
	}	
	
	function randomReference($cmsDocument) {
		$cmsDocument->flush();
		$cmsDocument->addDocumentType("docImCap");
		$cmsDocument->addConstraint("active","1");
		$cmsDocument->setPageSize(1);
		$totalDocs = $cmsDocument->totalDocuments();
		$randomPage = (rand()%$totalDocs);
		$cmsDocument->setPageNumber($randomPage);
		$cmsDocument->resetIterator();
		$reference = $cmsDocument->nextDocument();
		return $reference;
	}
    	
	function randomPassword($length = 6) {
		//set an array of acceptable characters for our password
		$characters = array("a", "b", "c", "d", "e", "f", "g", "h", "j", "k", "m", "n", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "2", "3", "4", "5", "6", "7", "8", "9");
		$password = '';
		$i = 0;
		while ($i < $length) {
			$password = $password.$characters[rand(0, (count($characters)-1))];
			$i++;
		}
		return $password;
	}
	
	
	function myPrintR( &$thing, $label ="" ) {
		if ( 0 < strlen($label)){
			echo "<h5>$label</h5>";
		}
		print "<pre>---\n"; print( gettype($thing) . "\n\n"); print_r($thing); echo "\n---\n</pre>";
	}
	
	function getDocumentTypeForDocumentTypeCode($documenttypecode, &$db){
		$q = "SELECT * FROM documenttype WHERE documenttypecode='" . $documenttypecode ."'";
		$db->executeQuery($q);
		if (($o = $db->nextObject())){
			return $o;
		} else {
			return  null;
		}
	}
	
	function getDocumentTypeCodeFromFormId($formid, &$db) {
		$db->executeQuery("SELECT documenttypecode FROM formdescriptor WHERE formid='".$formid."'");
		if ($row = $db->nextRow()) {
			$db->executeQuery("SELECT sourcequery FROM formelement WHERE elementid='".$row[0]."'");
			if ($row = $db->nextRow()) {
				$db->executeQuery($row[0]);
				if ($row = $db->nextRow()) {
					return $row[0];
				}
			}
		}
		return false;
	}
	
	function microtimeFloat() {
		list($usec, $sec) = explode(" ", microtime());
		return ((float)$usec + (float)$sec);
	}
	
	function printDocumentPermissionInformation(&$authInfo , &$document) {	
		if ( $authInfo->usertype == CMS_USERTYPE_SU ) {
			echo "(" . $document->uid . "," . $document->gid . ",". $document->permissions .")";
		}
	}
	
	function clearItemsFromCacheWithDocumentCode($documentCode, $cacheDir) {
		$deletedItems = 0;
		if (!is_null($documentCode) && !is_null($cacheDir)) {
			$d = dir($cacheDir);
			while (false !== ($entry = $d->read())) {

				$patternHeader = "/^$documentCode.*\.header$/";
				$patternDat = "/^$documentCode.*\.dat$/";
				
				if (preg_match($patternHeader,$entry) |  preg_match($patternDat,$entry)) {
					//echo $cacheDir . "/" . $entry . "<br />";					
					if (unlink($cacheDir . "/" .$entry )) {
						$deletedItems++;
					}
				}
			}
			$d->close();
		}	
		return $deletedItems;
	}
	
	function documentWithIdFromCache($id, &$cmsDocument, $flush=false){
		static  $documentCache;
		
		if ($flush && !is_null($documentCache)){
			$documentCache = null;
		}
		
		if (is_null($documentCache))
			$documentCache= array();
		
		
		if (!key_exists($id, $documentCache)){			
			if (!is_null($id) && $id > 0 )   {
		  		$documentCache[ $id ] = $cmsDocument->openDocument($id);
			}
		}
		
		//extra check
		if (key_exists($id, $documentCache))
			return $documentCache[ $id ];		
		else 
			return null;
	}
	
	// this is a little function that performs much like the document with id from cache
	// however, it has its own cms document so we dont run into key mapping stress
	// and it also restricts to a site...
	function cachedDocumentWithIdForSite($id, $site){
		
		// fill me in..
		
		return null;
	}

	
	
	//simple string email validation
	function isEmailAddress($emailAddress) {
		return preg_match(
      		'/^[-_a-z0-9]+(\.[-_a-z0-9]+)*@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]{2,6}$/', 
      		strtolower($emailAddress) ); 		
	}
	
	function convertMysqlDatestamp($datestamp) {
		$Y = substr($datestamp, 0, 4);
		$m = substr($datestamp, 4, 2);
		$d = substr($datestamp, 6, 2);
		$H = substr($datestamp, 8, 2);
		$i = substr($datestamp, 10, 2);
		$s = substr($datestamp, 12, 2);	
		$date = date("Y-m-d H:i:s", mktime($H,$i,$s,$m,$d,$Y));
		return $date;
	}
	
	function tinyMceEditorWithIdAndContent(&$id, &$content, &$options) {
		
		$tinyMceCss = extractStringWithKeyFromArray('tinyMceCss', $options, TINYMCE_CSS );
		
		//echo $tinyMceCss;
		
		$tinyMceTags = extractStringWithKeyFromArray('tinyMceTags', $options, TINYMCE_TAGS);
		$tinyMceStyles = extractStringWithKeyFromArray('tinyMceStyles', $options, TINYMCE_STYLES);
		
		$inputClass= extractStringWithKeyFromArray('inputClass',$options, null);
		if (!is_null($inputClass)) {
			$inputClass= "class=\"$inputClass\"";
		}
		
		return <<< EOD
<script language="javascript" type="text/javascript">
						tinyMCE.init({
						      mode : "exact",
						      elements : "$id",
						      theme : "advanced",
						      plugins : "table,advhr,iespell,insertdatetime,searchreplace,contextmenu,paste,advlink,customimage,customlink",
						      theme_advanced_buttons1 : "bold,italic,underline,strikethrough,separator,justifyleft,justifycenter,justifyright,justifyfull,separator,bullist,numlist,hr,separator,styleselect,formatselect,separator,customlink,unlink,separator,cut,copy,pastetext,iespell,separator,code,separator,customimage",
						      theme_advanced_buttons2: "",
						      theme_advanced_buttons3 : "",
						      theme_advanced_blockformats : "$tinyMceTags",
						      theme_advanced_toolbar_location : "top",
						      theme_advanced_styles: "$tinyMceStyles",
						      theme_advanced_toolbar_align : "left",
						      theme_advanced_path_location : "bottom",
						      plugin_insertdate_dateFormat : "%Y-%m-%d",
						      plugin_insertdate_timeFormat : "%H:%M:%S",
							valid_elements : "*[*]",
						      file_browser_callback : "mcFileManager.filebrowserCallBack",
						      theme_advanced_resize_horizontal : false,
						      theme_advanced_resizing : false,
						      content_css: "$tinyMceCss",
						      width:  "640",
						      theme_advanced_resizing : false
						});
						</script>
						<textarea id="$id" name="$id" rows="20" cols="100" >$content</textarea>
EOD;
	}
	
	function jsDualStateCheckBox($id,$onValue,$offValue,$checked){
		$cbid= $id . "_cb";
		$cbChecked = $checked ? "checked=\"checked\"" : "";
		$value = $checked ? $onValue : $offValue;
		$form= <<< EOD
		<input type="checkbox" id="$cbid" name="$cbid" $cbChecked onClick="jsDualStateToggle(this,'$id','$onValue','$offValue');"/>
		<input type="hidden" id="$id" name="$id" value="$value"/>
EOD;
		return $form;
	}
	
	function redirectCleanly( $url ) {
		while (@ob_end_clean());//we clean all output buffers..
		header("Location:" . $url , true);				
		die();
	}
	
	
	function dieWithInternalServerError( $message ){
		
		while (@ob_end_clean());//we clean all output buffers..	
		//how the hell do we nuke the headers.?
		header("http/1.0 500 Internal Server Error", true);
		die($message);
	}
	
	
	function printCheckBoxList($id, $name, &$values, $onClick, $checked=false, $start=0, $class="checkList", $options=null){

		$descriptionStringKeyPath = extractStringWithKeyFromArray("descriptionStringKeyPath", $options, null);
		$valueKeyPath = extractStringWithKeyFromArray("valueKeyPath", $options, null);
?>
 <ul id="<?= $id ?>" class="<?= $class ?>">
<?php
$i=$start;
if (is_array($values) && 0 < count($values))
foreach ($values as $key => $value){

	$itemId = $name . "_" . $i;
?>	
<li><label for="<?= $itemId ?>"><input id="<?= $itemId ?>" name="<?= $name ?>[]" type="checkbox" value="<?= (is_null($valueKeyPath) ? $value : $value->{$valueKeyPath}) ?>" onclick="<?= $onClick?>" <?= ( $checked ? "checked=\"checked\"" : "") ?> /><?= (is_null($descriptionStringKeyPath) ? $value : $value->{$descriptionStringKeyPath}) ?></label></li>
<?
	$i++;
}
?>		
    </ul>
		
<?	
	return $i;
	}
	
	
	
	function printDualCheckBoxList($id, &$values, &$selected, $options=null){
		
		$selectedValues = array();
		
		$valueKeyPath = extractStringWithKeyFromArray("valueKeyPath", $options, null);
		$unselectedValues = array();
		
		////////////////////////////////////////////////
		
		$valuesGids = array();
		foreach($values as $key => $value){
			$valuesGids[$key] = (is_null($valueKeyPath) ? $value : $value->{$valueKeyPath});
		}
		
		$selectedGids = array();
		foreach($selected as $key => $value){
			$selectedGids[$key] = (is_null($valueKeyPath) ? $value : $value->{$valueKeyPath});
		}
		

		
		$unselectedGids = array_diff($valuesGids,$selectedGids);
		$actualSelectedGids = array_intersect($valuesGids, $selectedGids);
		

		////////////////////////////////////////////////
		if (0==count($selected)) {
			$unselectedValues = $values;
		} else {

		}

		$actualSelectedValues = array();
		foreach ($actualSelectedGids as $key=>$value) {
			$acutalSelectedValues[$key] =  $values[$key];
		}


		$acutalUnselectedValues = array();
		foreach ($unselectedGids as $key=>$value) {
			$acutalUnselectedValues[$key] =  $values[$key];
		}
?>

<div id="<?= $id ?>_checkList" class="checkListContainer">
	<div id="<?= $id ?>_checkListRight" class="leftCheckList">
<?php
	   	$end = printCheckBoxList($id ."_unselectedList", $id, $acutalUnselectedValues,"selectCheckBoxListItem(this);", false,0,"checkList", $options);
?>
	</div>		
	
	<div id="<?= $id ?>_checkListRight" class="rightCheckList">
<?php
	printCheckBoxList($id . "_selectedList", $id, $acutalSelectedValues, "deselectCheckBoxListItem(this);",  true, $end,"checkList", $options );
?>
	</div>
</div>		
<?php
	}

function &getSiteForHost($host, &$db) { // we need a db object, but dont want to assume there is a global one..static
	$sites=null;//set up the static cache..
	if (!($sites)){
		$sites = array();
	}
	//check the that the item is in the cache..
	if ( !(array_key_exists($host, $sites) && ($sites[$host]))){
		//look it up and bung it in the cache if we cant find it..
		$rows = $db->getAllAsObjects("SELECT t1.* FROM grouplist AS t1 WHERE t1.sitehost=?", ($a = array($host)) );
		if ($rows && is_array($rows) && 1 == count($rows))
			$sites[$host] = $rows[0];
		else {
			$null = array();
			return $null;
		}
	}
	return $sites[$host];
}


?>